package org.cnc.app;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.KeyEventPostProcessor;
import java.awt.KeyboardFocusManager;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

import org.cnc.core.CncCore;
import org.cnc.gui.SettingsPanel;
import org.cnc.gui.StatusPanel;
import org.cnc.rmi.interfaces.ModelDrawerInterface;
import org.jvnet.substance.skin.SubstanceRavenGraphiteGlassLookAndFeel;

public class Core implements KeyEventPostProcessor {

	/**
	 * 
	 */
	
	private JFrame frame;
	private ModelDrawerInterface modelDrawer;
	private SettingsPanel settingsPanel;
	private StatusPanel statusPanel;
	private CncCore core;
	private JButton button;
	private boolean machineStarted = false;
	protected boolean isFullScreenOn = false;
	protected short serverPort;
	protected String serverName;
	protected CoreSettings settings;
	
	private String drwrAddress;
	private String mchnAddress;
	
	private String drwrPort;
	private String mchnPort;
	
	public Core() throws RemoteException
	{
		frame = new JFrame("CncEmulator");

		core = new CncCore();
		
		String drawerAddress;
		String drawerPort = "3101";
		
		try
		{
			drawerAddress = "192.168.1.38";
			drawerAddress = (InetAddress.getLocalHost().getHostAddress()).toString();
			Registry drawerRegistry = LocateRegistry.getRegistry(
					drawerAddress,
						(new Integer(drawerPort)).intValue());
			
			// look up the remote object
			modelDrawer = (ModelDrawerInterface)(drawerRegistry.lookup("drawer"));
			core.connectModelDrawer( modelDrawer );
		}
		catch(Exception e)
		{
			System.out.println("Cannot connect to drawer!");
			modelDrawer = null;
		}
		
			settings = new CoreSettings();
			settingsPanel = new SettingsPanel( );
			settingsPanel.addChangeListener(core);		
			
			statusPanel = new StatusPanel();
			core.connectStatusPanel( statusPanel );
			
		    frame.setSize(1046, 755);
		    frame.setLocation(300,200);
		    frame.getContentPane().setLayout(new BorderLayout(0, 0));
	
		    JSplitPane splitPane_1 = new JSplitPane();
		    splitPane_1.setContinuousLayout(true);
		    splitPane_1.setOneTouchExpandable(true);
		    splitPane_1.setBackground(Color.DARK_GRAY);
		    splitPane_1.setForeground(Color.LIGHT_GRAY);
		    splitPane_1.setOrientation(JSplitPane.VERTICAL_SPLIT);
		    
		    splitPane_1.setLeftComponent(settingsPanel);
		    splitPane_1.setRightComponent(statusPanel);
		    
		    frame.getContentPane().add(splitPane_1, BorderLayout.CENTER);
		    
		    button = new JButton("\u0421\u0442\u0430\u0440\u0442");
		    button.addActionListener(new ActionListener() {
		    	public void actionPerformed(ActionEvent arg0) {
		    		
		    		if ( machineStarted )
		    		{
		    			((JButton)arg0.getSource()).setText( "Старт" );
		    			core.stopMachine();
		    			machineStarted = false;
		    		}
		    		else
		    		{
		    			((JButton)arg0.getSource()).setText( "Стоп" );
		    			core.startMachine();
		    			machineStarted = true;
		    		}
		    	}
		    });
		    
		    frame.getContentPane().add(button, BorderLayout.NORTH);
		    frame.getContentPane().add(settings, BorderLayout.NORTH);
		    frame.getContentPane().add(button, BorderLayout.EAST);
		    //modelDrawer.add(stopBtn, BorderLayout.NORTH);
		    
		    frame.setVisible(true);
		    frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

	}
	
	/**
	 * @param args
	*/
	public static void main(String[] args) {
        
		SwingUtilities.invokeLater ( new Runnable()
		{
			public void run ()
			{
				try
				{
				    UIManager.setLookAndFeel (new SubstanceRavenGraphiteGlassLookAndFeel()  );
					
				    Core application = new Core();
				    
				    KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventPostProcessor(application);
				}
				catch ( Exception e )
				{
				    System.out.println ( e );
				}
			}
		} );
		
	}

	@Override
	public boolean postProcessKeyEvent(final KeyEvent arg0) {
		
        if (arg0.getID() == KeyEvent.KEY_PRESSED) { 
        	
			if ( arg0.isControlDown() && arg0.getKeyCode() == KeyEvent.VK_S )
				showSettings();
			else if ( arg0.isControlDown() && arg0.getKeyCode() == KeyEvent.VK_F )
				toggleFullScreen();
			else if ( arg0.getKeyCode() == KeyEvent.VK_ESCAPE )
			{
	            WindowEvent wev = new WindowEvent(frame, WindowEvent.WINDOW_CLOSING);
	            Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
			}
			else
			{
				core.pressKey( arg0.getKeyCode() );
			}
        } 
		return false;
	}
	
	private void toggleFullScreen() {
		
	    frame.dispose();
		
		SwingUtilities.invokeLater(new Runnable() {
		  public void run() {
		
			if ( !isFullScreenOn )
			{
				GraphicsEnvironment localEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
				GraphicsDevice defaultDevice = localEnvironment.getDefaultScreenDevice();
				
				frame.setState(JFrame.MAXIMIZED_BOTH);
				frame.setUndecorated(true);
				
				defaultDevice.setFullScreenWindow(frame);
			
				isFullScreenOn = true;
				
				frame.setVisible(true);
				
				return;
			}
			else
			{
			
				GraphicsEnvironment localEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
				GraphicsDevice defaultDevice = localEnvironment.getDefaultScreenDevice();
				
				frame.setState(JFrame.NORMAL);
				frame.setUndecorated(false);
				
				defaultDevice.setFullScreenWindow(null);
				
				isFullScreenOn = false;
				
				frame.setVisible(true);
				
				return;
			}
			
		}});
	
	}

	private void showSettings()
	{
		if ( !settings.isVisible() )
			settings.setVisible(true);	
		else
			settings.setVisible(false);
	}
	
	public class CoreSettings extends JPanel
	{
		private JTextField txtDrawerIP;
		private JTextField txtMachineIP;
		private JTextField txtDrawerPort;
		private JTextField txtMachinePort;

		/**
		 * Create the panel.
		 */
		public CoreSettings()
		{
			setPreferredSize(new Dimension(120,120));
			setVisible( false );
			
			JLabel lblDrawer = new JLabel("Drawer");
			lblDrawer.setFont(new Font("Tahoma", Font.PLAIN, 16));
			lblDrawer.setHorizontalAlignment(SwingConstants.CENTER);
			
			JLabel lblMachine = new JLabel("Machine");
			lblMachine.setHorizontalAlignment(SwingConstants.CENTER);
			lblMachine.setFont(new Font("Tahoma", Font.PLAIN, 16));
			
			txtDrawerIP = new JTextField();
			txtDrawerIP.setHorizontalAlignment(SwingConstants.CENTER);
			txtDrawerIP.setFont(new Font("Tahoma", Font.PLAIN, 16));
			txtDrawerIP.setColumns(10);
			
			txtMachineIP = new JTextField();
			txtMachineIP.setFont(new Font("Tahoma", Font.PLAIN, 16));
			txtMachineIP.setColumns(10);
			
			JLabel label = new JLabel(":");
			label.setFont(new Font("Tahoma", Font.PLAIN, 16));
			
			JLabel label_1 = new JLabel(":");
			label_1.setFont(new Font("Tahoma", Font.PLAIN, 16));
			
			txtDrawerPort = new JTextField();
			txtDrawerPort.setFont(new Font("Tahoma", Font.PLAIN, 16));
			txtDrawerPort.setColumns(10);
			
			txtMachinePort = new JTextField();
			txtMachinePort.setFont(new Font("Tahoma", Font.PLAIN, 16));
			txtMachinePort.setColumns(10);
			
			JButton drwrReload = new JButton("Reload");
			drwrReload.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
					
				}
			});
			drwrReload.setFont(new Font("Tahoma", Font.PLAIN, 16));
			
			JButton mchnReload = new JButton("Reload");
			mchnReload.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					
				}
			});
			mchnReload.setFont(new Font("Tahoma", Font.PLAIN, 16));
			GroupLayout groupLayout = new GroupLayout(this);
			groupLayout.setHorizontalGroup(
				groupLayout.createParallelGroup(Alignment.LEADING)
					.addGroup(groupLayout.createSequentialGroup()
						.addContainerGap()
						.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING, false)
							.addComponent(lblMachine, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
							.addComponent(lblDrawer, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 99, Short.MAX_VALUE))
						.addPreferredGap(ComponentPlacement.RELATED)
						.addGroup(groupLayout.createParallelGroup(Alignment.LEADING, false)
							.addGroup(groupLayout.createSequentialGroup()
								.addComponent(txtDrawerIP, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
								.addPreferredGap(ComponentPlacement.RELATED)
								.addComponent(label)
								.addPreferredGap(ComponentPlacement.RELATED)
								.addComponent(txtDrawerPort, GroupLayout.PREFERRED_SIZE, 58, GroupLayout.PREFERRED_SIZE))
							.addGroup(groupLayout.createSequentialGroup()
								.addComponent(txtMachineIP, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
								.addPreferredGap(ComponentPlacement.RELATED)
								.addComponent(label_1)
								.addPreferredGap(ComponentPlacement.RELATED)
								.addComponent(txtMachinePort, 0, 0, Short.MAX_VALUE)))
						.addPreferredGap(ComponentPlacement.UNRELATED)
						.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
							.addComponent(drwrReload)
							.addComponent(mchnReload, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE))
						.addContainerGap(28, Short.MAX_VALUE))
			);
			groupLayout.setVerticalGroup(
				groupLayout.createParallelGroup(Alignment.LEADING)
					.addGroup(groupLayout.createSequentialGroup()
						.addContainerGap()
						.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
							.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
								.addComponent(txtDrawerIP, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
								.addComponent(label)
								.addComponent(txtDrawerPort, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
								.addComponent(drwrReload, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE))
							.addComponent(lblDrawer, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE))
						.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
							.addGroup(groupLayout.createSequentialGroup()
								.addGap(18)
								.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
									.addComponent(lblMachine, GroupLayout.PREFERRED_SIZE, 28, GroupLayout.PREFERRED_SIZE)
									.addComponent(txtMachineIP, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
									.addComponent(label_1)
									.addComponent(txtMachinePort, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
							.addGroup(groupLayout.createSequentialGroup()
								.addGap(18)
								.addComponent(mchnReload, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE)))
						.addContainerGap(216, Short.MAX_VALUE))
			);
			setLayout(groupLayout);

		}
	}

}
